package com.es.demo.service.impl;

import com.es.demo.document.ProductInfo;
import com.es.demo.repository.ProductInfoRepository;
import com.es.demo.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.*;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ProductServiceImpl extends BasicEsServiceImpl<ProductInfo> implements ProductService {
    @Autowired
    private ProductInfoRepository productInfoRepository;

    @Override
    public Boolean save(ProductInfo... productInfo) {
//        Iterable<ProductInfo> save = elasticsearchTemplate.save(productInfo);
//        for (ProductInfo info : save) {
//
//        }
        productInfoRepository.saveAll(Arrays.asList(productInfo));
        return true;
    }

    @Override
    public Boolean delete(Integer id) {
        productInfoRepository.deleteById(id);
        return null;
    }

    @Override
    public ProductInfo getById(Integer id) {
        Optional<ProductInfo> byId = productInfoRepository.findById(id);
        return byId.orElse(null);
    }

    @Override
    public List<ProductInfo> getAll() {
        List<ProductInfo> list = new ArrayList<>();
        productInfoRepository.findAll().forEach(list::add);
        return list;
    }

    @Override
    public List<ProductInfo> query(String keyword) {
        //es需要安装分词器插件IK
        //fuzzy 模糊查询，返回包含与搜索字词相似的字词的文档。
        //单条件查询
        /*FuzzyQueryBuilder fuzzyQuery = QueryBuilders.fuzzyQuery("description", keyword);
        Query searchQuery = new NativeSearchQueryBuilder()
                .withQuery(fuzzyQuery)
                .build();*/
        //多条件查询
        /*BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        FuzzyQueryBuilder fuzzyQuery = QueryBuilders.fuzzyQuery("description", keyword);
        FuzzyQueryBuilder fuzzyQuery2 = QueryBuilders.fuzzyQuery("productName", keyword);
        //或者 or
        boolQueryBuilder.should(fuzzyQuery);
        boolQueryBuilder.should(fuzzyQuery2);
        //并且 and
        boolQueryBuilder.must(fuzzyQuery);
        boolQueryBuilder.must(fuzzyQuery2);
        // 构建查询
        Query searchQuery = new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .build();*/
        //精准查询 =
//        TermQueryBuilder termQuery = QueryBuilders.termQuery("productName", keyword);
//        //精准查询 多个条件 in
////        TermsQueryBuilder termQuery = QueryBuilders.termsQuery("productName", keyword, keyword);
//        Query searchQuery = new NativeSearchQueryBuilder()
//                .withQuery(termQuery)
//                .build();

        //范围查询
//        RangeQueryBuilder price = new RangeQueryBuilder("price").gt(3000).lt(3200);
//        Query searchQuery = new NativeSearchQueryBuilder()
//                .withQuery(price)
//                .build();

        //分页，页码从0开始
        PageRequest of = PageRequest.of(0, 3);
        Query searchQuery = new NativeSearchQueryBuilder()
                //条件
//                .withQuery()
                //分页
                .withPageable(of)
                //排序
                .withSorts(SortBuilders.fieldSort("price").order(SortOrder.DESC))
                .build();
        SearchHits<ProductInfo> searchHits = this.elasticsearchRestTemplate.search(searchQuery,ProductInfo.class);
        SearchPage<ProductInfo> searchHits1 = SearchHitSupport.searchPageFor(searchHits, searchQuery.getPageable());
        List<ProductInfo> list = searchHits.get().map(SearchHit::getContent).collect(Collectors.toList());
        Page<ProductInfo> page = new PageImpl<>(list, searchHits1.getPageable(), searchHits1.getTotalElements());

        for (ProductInfo productInfo : list) {
            System.out.println(productInfo);
        }
        return list;
    }
}
